package com.heima.search.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.pojo.UserSearchDto;
import com.heima.search.service.ApUserSearchService;
import com.heima.search.service.ArticleSearchService;
import com.heima.utils.thread.ApUserThreadUtil;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.Operator;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: JW
 * @Description: TODO
 * @DateTime: 2022-02-18 9:47
 **/
@Service
public class ArticleSearchServiceImpl implements ArticleSearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private ApUserSearchService apUserSearchService;

    /**
     * @param userSearchDto
     * @Author: JW
     * @Description: TODO 文章搜索
     * @Date: 10:03 2022-02-18
     * @Param: [userSearchDto]
     * @return: com.heima.model.common.dtos.ResponseResult
     */
    @Override
    public ResponseResult search(UserSearchDto userSearchDto) throws IOException {

        if (ObjectUtils.isEmpty(userSearchDto)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //异步调用 保存用户查询词条
        ApUser user = ApUserThreadUtil.getUser();
        if(user != null && userSearchDto.getFromIndex() == 0){
            apUserSearchService.save(userSearchDto.getSearchWords(), user.getId());
        }

        SearchRequest searchRequest = new SearchRequest("app_info_article");

        //词条查询
        searchRequest.source().query(QueryBuilders
                .queryStringQuery(userSearchDto.getSearchWords())
                .field("title").field("content").defaultOperator(Operator.OR));

        //时间排序
        searchRequest.source().sort("publishTime");

        //分页
        searchRequest.source().from(userSearchDto.getPageNum()).size(userSearchDto.getPageSize());

        //高亮
        searchRequest.source().highlighter(new HighlightBuilder().field("title")
                .preTags("<font style='color: red; font-size: inherit;'>").postTags("</font>")
                .requireFieldMatch(false));

        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //结果集
        List<Map> list = new ArrayList<>();

        //解析结果
        SearchHits searchHits = response.getHits();

        //文档数组
        SearchHit[] hits = searchHits.getHits();

        for (SearchHit hit : hits) {

            //将对象反序列化
            Map map = JSON.parseObject(hit.getSourceAsString(), Map.class);

            if (hit.getHighlightFields() != null && hit.getHighlightFields().size() > 0){

                HighlightField highlightField = hit.getHighlightFields().get("title");

                if (highlightField != null){
                    //取出高亮词汇
                    String highlightTitle = highlightField.getFragments()[0].string();

                    //设置成为高亮词
                    map.put("h_title",highlightTitle);
                }
            }else {
                //放入原始数据
                map.put("h_title",map.get("title"));
            }

            list.add(map);
        }

        return ResponseResult.okResult(list);
    }
}
